package modellstadt.rules;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;

import processing.core.PApplet;
import modellstadt.geom.Face;
import modellstadt.util.ProcessingOBJExporter;

/**
 * @author dillenburger_b
 * 
 */
public abstract class Rule implements SplitCityConstants {
	PApplet applet;
	public HashMap<Integer, Rule> rules=new HashMap<Integer, Rule>();

	public static  int[] getColors(PApplet app) {
		int[]colors=new int[40];
		for (int i = 0; i < colors.length; i++) {
			colors[i] = app.color(255);
		}
		colors[STREET] =  app.color(100);
		colors[ROOF] =  app.color(255, 0, 0);
		colors[BUILDINGSIDE] =  app.color(0, 0, 255);
		colors[TRACK] =  app.color(100);
		colors[BOARDWALK] =  app.color(100);
		colors[ROOFGABLE] =  app.color(50);
		colors[ROOFFACADE] =  app.color(255,0,0);
		colors[GLASS] =  app.color(0,255,255);
		return colors;
	}

	public static void exportOBJ(ArrayList<Face>faces,String filename) {
		ProcessingOBJExporter exporter = new ProcessingOBJExporter(filename);
		// Mesh mesh=new Mesh(faces);
		for (int j = 0; j < 20; j++) {
			exporter.group("" + j);
			for (int i = 0; i < faces.size(); i++) {
				Face f = faces.get(i);
				if (f.type == j)
					f.display3D(exporter);
			}
		}
		exporter.dispose();
		// mesh.saveAsOBJ(filename);
	}

	/**
	 * 
	 */
	public Rule() {
		// TODO Auto-generated constructor stub
		rules = new HashMap<Integer, Rule>();
	}

	/**
	 * @param selector
	 * @param rule
	 */
	public void registerRule(int selector, Rule rule) {
		rules.put(selector, rule);
	}

	/**
	 * @param faces
	 * @param seed
	 * @return
	 */
	public ArrayList<Face> interpret(ArrayList<Face> faces, Random seed) {
		ArrayList<Face> result = new ArrayList<Face>();
		for (int i = 0; i < faces.size(); i++) {
			result.addAll(interpret(faces.get(i), seed));
		}
		return result;
	}

	public ArrayList<Face> interpret(Face face, Random seed) {
		int nReplacements;
		ArrayList<Face> faces = new ArrayList<Face>();
		faces.add(face);
		do {
			nReplacements = 0;
			ArrayList<Face> result = new ArrayList<Face>();
			for (int i = 0; i < faces.size(); i++) {
				Face cFace = faces.get(i);
				if (cFace.end) {
					result.add(cFace);
				} else {
					Rule rule = rules.get(cFace.type);
					if (rule != null) {
						nReplacements++;
						result.addAll(rule.interpret(cFace, seed));
					} else {
						result.addAll(replace(cFace, seed));
					}
				}
			}
			faces = result;
		} while (nReplacements > 0);
		return faces;
	}

	/**
	 * @param face
	 * @param seed
	 * @return
	 */
	public ArrayList<Face> replace(Face face, Random seed) {
		ArrayList<Face> newFaces = new ArrayList<Face>();
		newFaces.add(face);
		return newFaces;
	}
}
